<?php

namespace app\admin\service\auth;
use app\admin\service\CurdService;
use app\admin\validate\auth\AdminValidate;
use app\extend\MiAuth;
use app\model\auth\Admin;
use app\model\auth\AdminGroup;
use app\model\auth\AdminGroupAccess;
use app\model\auth\AdminRule;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Cache;
use think\facade\Config;
use think\Model;
use function config;
use function request;
use function validate;

class AdminService
{

    protected Model $model;

    protected string $tokenCachePre = 'admin_';

    public function __construct(){
        $this->model = new Admin();
    }

    /**
     * 根据id获取详情
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function info(int $id){
        return $this->model->withoutField("password")->with(['groups'])->find($id);
    }


    /**
     * 编辑用户信息
     * @throws \Exception
     */
    public function save($post, string $type){
        if (!in_array($type, ['add', 'edit'])){
            throw new \Exception('type值错误');
        }
        $id = $post['id'] ?? '';

        // 验证表单数据
        validate(AdminValidate::class)->scene($type)->check($post);

        $group_id = $post['group_id'];
        unset($post['group_id']);
        $password = $post['password']??'';
        if ($password){ // 设置了新密码
            $post['password'] = md5($password);
        }else{
            unset($post['password']);
        }
        $curdSer = new CurdService(new Admin());
        if ($type == 'add'){
            $admin = $curdSer->create($post);
        }else{
            $admin = $curdSer->update($post, ['id' => $id]);
        }
        // 删除旧的角色关联
        AdminGroupAccess::where('uid', $admin->id)->delete();
        // 添加新的角色关联
        AdminGroupAccess::create([
            'uid' => $admin->id,
            'group_id' => $group_id
        ]);
    }

    public function getLoginId(){
        return Cache::get($this->tokenCachePre.$this->getToken());
    }

    public function getLoginInfo(){
        $id = $this->getLoginId();
        return $this->info($id);
    }

    public function getToken(){
        return request()->header('mi-token');
    }

    public function checkToken(): bool
    {
        $token = $this->getToken();
        $cacheToken = Cache::get($this->tokenCachePre.$token);
        if ($cacheToken){
            return true;
        }
        return false;
    }

    public function setLoginToken($token, $adminId){
        Cache::set($this->tokenCachePre.$token, $adminId, 60*60*24);
    }

    public function logout(){
        Cache::delete($this->tokenCachePre.$this->getToken());
    }

    /**
     * 获取登录用户的所有目录和菜单
     * @param $adminId
     * @return void
     */
    public function getLoginMenus(){
        $query = AdminRule::where('rule_type', '<>', 3)
            ->where('status', 1)
            ->order('sort desc');

        $adminId = $this->getLoginId();
        $super = config('app.super_admin');

        if($adminId != $super){ // 不是超级管理员
            // 获取用户拥有的所有权限规则ids[]
            $auth = MiAuth::instance();
            $groups = $auth->getGroups($adminId);
            if (count($groups) == 0){
                $gids = [];
            }else{
                $gids = AdminGroup::where('id', $groups[0]['group_id'])->limit(1)->value('rules');
            }

            // 添加条件
            $query->whereIn('id', $gids);
        }

        $auths = $query->select();

        // 组装二维数组
        $arSer = new AdminRuleService();
        return $arSer->childrenTree($auths);
    }


    /**
     * 获取登录用户的所有权限规则（包含目录、菜单、权限）
     * @return array
     */
    public function getLoginRules(): array
    {
        // 查询前的准备(基础查询条件)
        $query = AdminRule::where('status', 1)->where('rule_type', 3)
            ->order('sort desc')
            ->cache(true, 60);

        $super = config('app.super_admin');
        $adminId = $this->getLoginId();

        if( $adminId != $super){ // 不是超级管理员
            // 获取用户拥有的所有权限规则ids[]
            $auth = MiAuth::instance();
            $groups = $auth->getGroups($adminId);
            if (count($groups) == 0){
                $gids = [];
            }else{
                $gids = AdminGroup::where('id', $groups[0]['group_id'])->limit(1)->value('rules');
            }
            // 添加条件
            $query = $query->whereIn('id', $gids);
        }

        return $query->column('name');
    }


    /**
     * 验证当前登陆admin的权限
     * @param $rule
     * @return bool
     * 验证admin权限
     */
    function checkLoginAuth($rule): bool
    {

        // 获取当前用户
        $adminId = $this->getLoginId();

        // 超级管理员不验证权限
        $super = Config::get('app.super_admin');
        if($super == $adminId){
            return true;
        }

        // 验证权限
        $auth = MiAuth::instance();
        // check中会将所有字母转为小写
        return $auth->check($rule, $adminId);
    }

}
